// Copyright 2010 Alexandre Tristan St-Cyr <tristan.stcyr@gmail.com>

package com.codeplex.loadjava;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


public class Repository implements IRepository {
	
	private static final String SELECT_FOLDER_ID =
		"select Id from [Repository.Item].Folders where Name = ?";
	
	private static final String NEW_ID_PROC =
		"{?=call Repository.NewIdInterval( ?, ?, ?, ?)}";
	
	private static String INSERT_FOLDER =
		"insert into [Repository.Item].Folders (Folder, Name) values(NULL, ?);";
	
	protected Connection connection;
	
	public Repository(Connection connection) {
		this.connection = connection;
	}
	
	@Override
	public Long getFolderId(String folderName) throws SQLException {
		Long folderId = selectFolderId(folderName);
		if (folderId == null) {
			createFolder(folderName);
			folderId = selectFolderId(folderName);
			if (folderId == null) {
				throw new SQLException("Repository folder could not be created");
			}
		}
		return folderId;
	}
	
	@Override
	public long newIdInterval(String sequence, long count) throws SQLException {
		CallableStatement proc = connection.prepareCall(NEW_ID_PROC);
		proc.registerOutParameter(1, java.sql.Types.BIGINT);
		proc.registerOutParameter(5, java.sql.Types.BIGINT);
		proc.setString(2, "Java.Class");
		proc.setString(3, sequence);
		proc.setLong(4, count);
		proc.setLong(5, 0);
		proc.execute();
		return proc.getLong(5);
	}
	
	private void createFolder(String folderName) throws SQLException {
		PreparedStatement statement = connection.prepareStatement(INSERT_FOLDER);
		statement.setString(1, folderName);
		statement.execute();
	}
	
	private Long selectFolderId(String folderName) throws SQLException {
		PreparedStatement statement = connection.prepareStatement(SELECT_FOLDER_ID);
		statement.setString(1, folderName);
		ResultSet results = statement.executeQuery();
		if (!results.next())
		{
			return null;
		}
		return results.getLong(1);
	}
}
